JavaScript中for-in 和 for-of的区别

发布 : 2018-12-14 浏览 :

JS里面做循环最普通的是绝大多数编程语言都有的 for ([initialization]; [condition]; [final-expression]) , 比如我们遍历一个数组可能会这样写

1
2
3
for (var i = 0, len = arr.length; i < len; i++) {
...
}

可以看出来这样写写法上比较复杂, 需要计算length

ES5 中为了更方便的遍历数组, 提供了 forEach , 写法上简洁了很多

1
arr.forEach(item => { ... })

但是这种也会有一个很不方便的地方就是无法 break , 想象一下我们遍历数组, 可能第一个元素就满足某种条件而需要终止循环, 这样的写法是没有办法终止的, 只能傻乎乎的把数组全部遍历一遍。

还有另外一种 for-in 的循环, 它主要被用来遍历 enumerable 类型的对象, 比如

1
2
3
4
5
6
7
var obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(`key: ${key}, value: ${ obj[key] }`)
}
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3

但是 for-in 形式的循环有个问题就是会遍历出原型链上的属性, 比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
aArray = [1,2,3]
aArray.name = 'demo'
Array.prototype.arrCustomFn = function() {};
Object.prototype.objCustomFn = function() {};
for(let index in aArray){
console.log(index);
}

// 0
// 1
// 2
// name
// arrCustomFn
// objCustomFn

所以很多Lint系列会要求使用 hasOwnProperty 来先判断是否是自有的属性

1
2
3
4
5
6
7
var obj = { a: 1, b: 2, c: 3 };
const hasOwn = Object.prototype.hasOwnProperty
for (let key in obj) {
if (hasOwn.call(obj, key)) {
console.log(`key: ${key}, value: ${ obj[key] }`)
}
}

ES6中增加了 for-of , 既保持了简洁的风格, 有弥补了forEach和for-in循环的不足之处, 而且应用范围很广泛, 所有的 Iterable 对象, Iterable对象就是含有 [Symbol.iterator] 属性的对象, 比如String、Array、Set、
Map、arguments、NodeList等。 在循环中还可以直接使用 break 中断循环

1
2
3
4
5
6
7
8
9
10
11
12
13
let iterable = [1, 2, 3];

for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3
for (let value of iterable) {
if (value === 2) break;
console.log(value);
}
// 1

通过对比可以看出, 不同于for-in 遍历出来的是键名, for-of 遍历出来的是值, 所以如果需要遍历对象的话, 必须先使用Object.keys()

1
2
3
for (var key of Object.keys(someObject)) {
console.log(key + ': ' + someObject[key]);
}

结论:

  • 不需要中途终止的可以直接使用 forEach

  • 需要遍历对象时优先使用for-in, 可能需要搭配 hasOwnProperty 使用

  • 遍历其它 Iterable 类型的集合时使用for-of

本文作者 : Shuai Liang
原文链接 : http://liangshuai.me/2018/12/14/yuque/JavaScript中for-in 和 for-of的区别/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹